package com.ben.multiple.schedule;

import java.time.LocalDateTime;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;

/**
 * 多线程执行定时任务的第二种方式
 * 创建  SchedulingConfigurer，定制 TaskScheduler
 * 定制的 TaskScheduler 会管理非异步的定时任务线程。
 * 非异步的定时任务，从定制的 线程池中拿线程使用，多个定时任务同步执行，根据线程的阻塞策略执行，当线程池大于定时任务数时，不会阻塞。
 * 同一个定时任务，每次执行的线程会不同。
 * 同一个定时任务，当上个任务还没执行完时，下个任务不会开始执行。
 * 异步线程，不会被 自定义的 TaskScheduler 控制，依旧是每次执行时创建新的线程。
 *
 * @author BenJin Yin
 * @date 2021/1/22
 */
@Component
public class MySchedulingConfigurer implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        // 线程池大小
        taskScheduler.setPoolSize(10);
        // 线程优先级
        taskScheduler.setThreadPriority(Thread.MIN_PRIORITY);
        // 线程名前缀
        taskScheduler.setThreadNamePrefix("customTaskScheduler");
        // 当应用停止时，定时任务的线程也停止。
        taskScheduler.setDaemon(false);
        // 线程结束等待时长
        taskScheduler.setAwaitTerminationSeconds(10);
        // true : 应用关闭时，等待任务线程结束；程序异常关闭时，会存在定时任务线程没有关闭的问题。
        taskScheduler.setWaitForTasksToCompleteOnShutdown(false);
        taskScheduler.afterPropertiesSet();
        taskRegistrar.setScheduler(taskScheduler);
    }

//    @Scheduled(cron = "*/2 * * * * *")
    public void mySchedulingConfigurerTask91() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("mySchedulingConfigurerTask91 ：" + LocalDateTime.now() + "==" + Thread.currentThread().getName());
    }
}
